#include <iostream>
#include <filesystem>
#include <string>
#include <fstream>
#include <chrono>
#include <ctime>
#include <iomanip>

namespace fs = std::filesystem;

// 帮助函数：格式化文件大小
std::string format_file_size(uintmax_t size) {
    constexpr uintmax_t KB = 1024;
    constexpr uintmax_t MB = 1024 * KB;
    constexpr uintmax_t GB = 1024 * MB;

    if (size < KB) {
        return std::to_string(size) + " B";
    } else if (size < MB) {
        return std::to_string(size / KB) + " KB";
    } else if (size < GB) {
        return std::to_string(size / MB) + " MB";
    } else {
        return std::to_string(size / GB) + " GB";
    }
}

// 帮助函数：格式化时间戳
std::string format_time(const fs::file_time_type& time) {
    auto systemTime = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
        time - fs::file_time_type::clock::now() + std::chrono::system_clock::now());
    
    std::time_t ctime = std::chrono::system_clock::to_time_t(systemTime);
    
    std::stringstream ss;
    ss << std::put_time(std::localtime(&ctime), "%Y-%m-%d %H:%M:%S");
    return ss.str();
}

void demonstrate_filesystem() {
    std::cout << "  C++17文件系统库(filesystem)演示:\n\n";
    
    // 1. 基本路径操作
    fs::path current_path = fs::current_path();
    std::cout << "  当前路径: " << current_path << '\n';
    
    fs::path example_path = current_path / "example" / "data.txt";
    std::cout << "  示例路径: " << example_path << '\n';
    std::cout << "  根名: " << example_path.root_name() << '\n';
    std::cout << "  根路径: " << example_path.root_path() << '\n';
    std::cout << "  相对路径: " << example_path.relative_path() << '\n';
    std::cout << "  父路径: " << example_path.parent_path() << '\n';
    std::cout << "  文件名: " << example_path.filename() << '\n';
    std::cout << "  不带扩展名的文件名: " << example_path.stem() << '\n';
    std::cout << "  扩展名: " << example_path.extension() << '\n';
    
    // 2. 检查路径是否存在
    fs::path temp_dir = current_path / "temp";
    if (!fs::exists(temp_dir)) {
        std::cout << "\n  创建临时目录: " << temp_dir << '\n';
        fs::create_directory(temp_dir);
    }
    
    // 3. 创建临时文件
    fs::path temp_file = temp_dir / "example.txt";
    std::cout << "  创建文件: " << temp_file << '\n';
    
    // 写入一些内容
    {
        std::ofstream file(temp_file);
        file << "C++17 filesystem库示例内容\n";
        file << "这是一个测试文件。\n";
    }
    
    // 4. 读取文件信息
    if (fs::exists(temp_file)) {
        std::cout << "  文件存在: " << temp_file << '\n';
        std::cout << "  文件大小: " << format_file_size(fs::file_size(temp_file)) << '\n';
        
        auto last_write_time = fs::last_write_time(temp_file);
        std::cout << "  最后修改时间: " << format_time(last_write_time) << '\n';
        
        auto status = fs::status(temp_file);
        std::cout << "  文件类型: ";
        switch (status.type()) {
            case fs::file_type::regular: std::cout << "常规文件\n"; break;
            case fs::file_type::directory: std::cout << "目录\n"; break;
            case fs::file_type::symlink: std::cout << "符号链接\n"; break;
            default: std::cout << "其他\n"; break;
        }
        
        std::cout << "  权限: ";
        std::cout << ((status.permissions() & fs::perms::owner_read) != fs::perms::none ? "r" : "-");
        std::cout << ((status.permissions() & fs::perms::owner_write) != fs::perms::none ? "w" : "-");
        std::cout << ((status.permissions() & fs::perms::owner_exec) != fs::perms::none ? "x" : "-");
        std::cout << '\n';
    }
    
    // 5. 目录遍历
    std::cout << "\n  遍历目录: " << current_path << '\n';
    int max_entries = 5;  // 限制显示条目数
    int count = 0;
    
    for (const auto& entry : fs::directory_iterator(current_path)) {
        if (count++ >= max_entries) {
            std::cout << "  ... 更多文件 ...\n";
            break;
        }
        
        std::cout << "  " << entry.path().filename() << " ";
        if (fs::is_regular_file(entry)) {
            std::cout << "(文件, " << format_file_size(fs::file_size(entry)) << ")";
        } else if (fs::is_directory(entry)) {
            std::cout << "(目录)";
        } else if (fs::is_symlink(entry)) {
            std::cout << "(符号链接)";
        }
        std::cout << '\n';
    }
    
    // 6. 通过特定扩展名查找文件
    std::cout << "\n  递归查找所有.cpp文件:\n";
    count = 0;
    for (const auto& entry : fs::recursive_directory_iterator(current_path)) {
        if (entry.path().extension() == ".cpp") {
            if (count++ >= max_entries) {
                std::cout << "  ... 更多.cpp文件 ...\n";
                break;
            }
            std::cout << "  " << entry.path().filename() << '\n';
        }
    }
    
    // 7. 清理临时文件
    std::cout << "\n  清理临时文件...\n";
    fs::remove(temp_file);
    fs::remove(temp_dir);
} 